package ie.dcu.spca.data.db;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import ie.dcu.spca.data.CategoryDataManager;
import ie.dcu.spca.data.PriceUnitDataManager;
import ie.dcu.spca.data.ProductDataManager;
import ie.dcu.spca.model.Bean;
import ie.dcu.spca.model.bean.PriceUnit;
import ie.dcu.spca.model.bean.Product;
import ie.dcu.spca.model.dao.ProductDao;

public class DBProductDataManager extends DBBasicDataManager implements
        ProductDataManager {

    private static ProductDao pDao = new ProductDao();

    private static List<Product> productsCache = null;

    private ProductDao productDao() {
        productsCache = null;
        return pDao;
    }

    private static PriceUnitDataManager unitManager;
    private static CategoryDataManager categoryManager;

    public DBProductDataManager() {
        super();
    }

    @Override
    public void loadDefault(PriceUnitDataManager unitM,
            CategoryDataManager categoryM) {
        unitManager = unitM;
        categoryManager = categoryM;
    }

    @Override
    public int create(String name, String barcode, double price,
            int categoryId, int unitId) {
        return productDao().insertProdect(name, price, barcode, unitId,
                categoryId);
    }

    @Override
    public int existOrCreate(int id, String name, String barcode, double price,
            int categoryId, int unitId) {
        Bean pBean = id == DEFAULT_PRODUCT_ID ? null : productDao().selectById(
                id);
        Product product = pBean == null ? null : (Product) pBean;
        boolean isSame = true;
        if (product != null) {
            if ((!product.getName().equals(name))
                    || (!product.getBarcode().equals(barcode))
                    || (product.getPrice() != (price))
                    || (product.getCategory_id() != (categoryId))
                    || (product.getUnit_id() != (unitId))) {
                isSame = false;
            }
        } else
            isSame = false;
        if (isSame){
            productDao().updateByBean(product);
            return id;
        }
        else
            return create(name, barcode, price, categoryId, unitId);
    }

    @Override
    public List<Product> get() {
        if (productsCache == null)
            productsCache = (List) productDao().selectAllBean();
        return productsCache;
    }

    @Override
    public Product get(int id) {
        if (id == DEFAULT_PRODUCT_ID) {
            return new Product(id, "Unknown", 999, "",
                    unitManager.getFirstId(), categoryManager.getLastId(),
                    now(), now(), now());
        } else
            return (Product) productDao().selectById(id);
    }

    @Override
    public Product get(int id, String barcode) {
        Product product = get(id);
        product.setBarcode(barcode);
        return product;
    }

    @Override
    public int getDefaultProductId() {
        return DEFAULT_PRODUCT_ID;
    }

    @Override
    public List<Map<String, Object>> getIdNameBarcodePriceMapList() {
        return getIdNameBarcodePriceMapList(getBeanList());
    }

    @Override
    public List<Map<String, Object>> getIdNameBarcodePriceMapList(
            List<Bean> beanList) {
        List<Map<String, Object>> beanML = new LinkedList<Map<String, Object>>();
        for (Bean b : beanList) {
            Product product = (Product) b;
            Map<String, Object> beanM = new HashMap<String, Object>();
            beanM.put(ID, product.getId());
            beanM.put(NAME, product.getName());
            beanM.put(BARCODE, (product.getBarcode()));
            beanM.put(PRICE, getPriceAndUnit(product));
            beanML.add(beanM);
        }
        return beanML;
    }

    @Override
    public void update(int id, String name, String barcode, double price,
            int categoryId, int unitId) {
        Product p = (Product) productDao().selectById(id);
        p.setName(name);
        p.setBarcode(barcode);
        p.setPrice(price);
        p.setCategory_id(categoryId);
        p.setUnit_id(unitId);
        productDao().updateByBean(p);
    }

    @Override
    public void delete(int id) {
        productDao().deleteById(id);
    }

    @Override
    public List<Bean> getBeanList() {
        return (List) get();
    }

    @Override
    public int getId(Bean bean) {
        return ((Product) bean).getId();
    }

    @Override
    public String getName(Bean bean) {
        return ((Product) bean).getName();
    }

    @Override
    public String getPriceAndUnit(Product product) {
        return Double.toString(product.getPrice()) + "/"
                + ((PriceUnit) unitManager.get(product.getUnit_id())).getName();
    }

}
